Classifiez automatiquement des biens de consommation

Sommaire

1. Préambule
 1.1 Problématique
 1.2 Objectifs dans ce projet
2. Import des librairies et réglage de Pandas
3.Déclaration des fonctions
4.Import des données
5. Analyse du DataSet
 5.1 Types des données
 5.2 Dimensions du DataFrame data
 5.3 Valeurs manquantes
 5.4 Cardinalité de data
6. Classification des produits grâce à leurs données textuelles descriptives
 6.1 Préparation, Analyse des Features Textuelles
  6.1.1 Sélection des features à traiter
  6.1.2 Fusion des colonnes 'product_name' et 'description'
  6.1.3 Traitement de la main category
   6.1.3.1 Extraction de la main category
   6.1.3.2 Statistique sur la main category
    6.1.3.2.1 Nombre d'articles par catégorie
    6.1.3.2.2 Nombre de mots en moyenne par description et par titre
 6.2 Traitement du texte
  6.2.1 Nettoyage et Normalisation du texte
  6.2.2 Lemmatisation du texte et Filtrage des Noms + Verbes
  6.2.3 Graphique Nombre de Mots par Catégorie par Traitement
  6.2.4 Création du dictionnaire dictTxt
  6.2.5 Création des vecteurs pondérés avec TF-IDF
  6.2.6 Réduction de dimension PCA / T-SNE
  6.2.7 Affichage de la classification des descriptions selon leurs catégories
  6.2.8 K-Means sur matrice T-SNE
  6.2.9 Affichage de la classification des descriptions selon leurs clusters
  6.2.10 Matrice de Confusion
  6.2.11 Calcul du Score ARI
7. Classification des produits grâce à leurs images
 7.1 Méthode SIFT
  7.1.1 Création du dictionnaire dictImages
  7.1.2 Ajout du path des images...
  7.1.3 ...et de leurs catégories respectives
  7.1.4 Calcul et regroupement de l'ensemble des descripteurs
  7.1.5 A propos du pre-processing des images
  7.1.6 Création du Bag of Virtual Words
  7.1.7 Création des histogrammes
  7.1.8 Réduction de dimension PCA + T-SNE
  7.1.9 Affichage de la classification des images selon leurs catégories
  7.1.10 K-Means sur matrice T-SNE
  7.1.11 Affichage de la classification des images selon leurs clusters
  7.1.12 Matrice de Confusion
  7.1.13 Calcul du Score ARI
 7.2 Méthode Transfert Learning avec VGG16
  7.2.1 Installer Keras
  7.2.2 Explication rapide de VGG16
  7.2.3 Création du modèle pré-entrainé par Keras
  7.2.4 Création du dictionnaire dictModel
  7.2.5 Ajout du path des images...
  7.2.6 ...et de leurs catégories respectives
  7.2.7 Préparation des images
  7.2.8 Extraction des histogrammes
  7.2.9 Clustering PCA / T-SNE
  7.2.10 Affichage de la classification des images selon leurs catégories
  7.2.11 K-Means sur matrice T-SNE
  7.2.12 Affichage de la classification des images selon leurs clusters
  7.2.13 Matrice de Confusion
  7.2.14 Calcul du Score ARI
8. Fusion des features Textes et Images
 8.1 Création et initialisation du dictionnaire dictTxt
 8.2 Fusion des vecteurs de caractéristiques de textes et d'images
 8.3 Clustering PCA / T-SNE
 8.4 Affichage de la classification des produits selon leurs catégories
 8.5 K-Means sur matrice T-SNE
 8.6 Graphique Description/Cluster
 8.7 Matrice de Confusion
 8.8 Calcul du Score ARI
9. Conclusion

1. Préambule

1.1 Problématique

L’entreprise "Place de marché”,
souhaite lancer une marketplace e-commerce.

Sur la place de marché, des vendeurs
proposent des articles à des acheteurs
en postant une photo et une description.

Pour l'instant, l'attribution de la catégorie
d'un article est effectuée manuellement par
les vendeurs et est donc peu fiable.
De plus, le volume des articles est
pour l’instant très petit.

Pour rendre l’expérience utilisateur
des vendeurs (faciliter la mise en ligne
de nouveaux articles) et des acheteurs (faciliter
la recherche de produits) la plus fluide
possible et dans l'optique d'un passage
à l'échelle, il devient nécessaire d'automatiser
cette tâche.

Il nous est demandé d'étudier la faisabilité
d'un moteur de classification des articles
en différentes catégories, avec un niveau
de précision suffisant.

1.2 Objectifs dans ce projet

Réaliser une première étude de faisabilité d'un moteur
de classification d'articles
basé sur une image et une
description pour l'automatisation de l'attribution
de la catégorie de l'article.

Analyser le jeu de données en réalisant un prétraitement
des images et des descriptions
des produits, une réduction
de dimension
, puis un clustering.

Les résultats du clustering seront présentés sous la forme
d’une représentation en deux dimensions, qui illustrera
le fait que les caractéristiques extraites permettent
de regrouper des produits de même catégorie
.

2. Import des librairies et réglage de Pandas

3. Déclaration des fonctions

J'ai décomposé en fonctions toutes les actions
clés réalisés dans ce projet afin :

L'ensemble des fonctions que j'ai écrit et utilisé
dans ce projet, pour les parties concernant
le traitement du texte, des images ou
du texte + images sont listés ci-dessous :

4. Import des données

5. Analyse du DataSet

5.1 Types des données

5.2 Dimensions du DataFrame data

5.3 Valeurs manquantes

5.4 Cardinalité de data

6. Classification des produits grâce
à leurs données textuelles descriptives

6.1 Préparation, Analyse des Features Textuelles

Dans cette partie nous allons classer
et regrouper nos produits en autant de
groupes qu'il existe de catégories.
Nous réaliserons cela à travers
notre moteur de classification à partir
des textes qui servent à les décrire.

L'objectif et d'obtenir du moteur
de classification, le regroupement
le plus proche par rapport au
classement de référence initial
.

Nous émettons l'hypothèse qu'un produit
peut-être attribué à une catégorie à
partir du vocubulaire utilisé dans sa description
.

2 features permettent de décrire un produit :

Nous allons mettre en place le moteur de classification.
Pour optimiser ses performances, nous allons devoir
pré-traiter les textes.

L’objectif est, d’une part, de débarrasser les textes
de tous les éléments inutiles qui n’apportent pas
d’information permettant d’identifier le produit
et d’autre part de normaliser le texte afin qu’un
mot utilisé dans la description d’un produit ait
exactement la même orthographe dans les autres
descriptions des autres produits (gestion de la casse,
de l’accord en genre et en nombre, verbes conjugués
convertis dans leur forme à l’infinitif, etc.)

Alors seulement nous pourrons créer
un bag of words constitué des seuls éléments
de vocabulaire ayant une importance pour
décrire nos produits.

Un bag of words nous sert à décrire un document.
Chaque mot représente une feature, une caractéristique.
L'ensemble de plusieurs caractéristiques permet de
décrire un produit et ainsi déterminer sa catégorie.

Notre moteur de classification attribuera à
chaque produit un vecteur de caractéristiques,
qui sera fonction des termes descriptifs inclus
dans sa description et pondéré avec l’ensemble
des termes existants pour décrire
l’ensemble des produits de notre jeu de données.

Pour améliorer les performances et également
permettre de visualiser la clusterisation des produits
de notre moteur de classification, nous procèderons
à une réduction en 2 dimensions des vecteurs de caractéristiques.

Via une clusterisation, notre moteur regroupera ensemble
les produits qu’il estimera appartenir à la même catégorie.

Enfin, nous pourrons évaluer notre moteur de
classification en comparant le regroupement de
l’ensemble des produits réalisé par notre moteur de
classification avec la catégorie réelle de chaque produit.

6.1.1 Sélection des features à traiter

Seules 3 features nous interresse dans cette partie :

6.1.2 Fusion des colonnes 'product_name' et 'description'

Je fusionne le titre et la description du produit
pour ne garder qu'un unique champ contenant
l'ensemble des termes décrivant l'objet.

6.1.3 Traitement de la main category

Chaque produit est caractérisé par la
catégorie qui lui est associé.
Il existe plusieurs niveaux de catégorie.
Pour l'exercice nous n'allons conserver
que la **catégorie principale**
de chaque produit.

6.1.3.1 Extraction de la main category

Création de la feature "category" qui contient
le nom de la catégorie principale de chaque produit :

6.1.3.2 Statistique sur la main category

6.1.3.2.1 Nombre d'articles par catégorie

Les produits sont parfaitements répartis entre les catégories :

6.1.3.2.2 Nombre de mots en moyenne par description et par titre

Je crée 3 colonnes contenant
le nombre de mots dans les features
:

Le nombre de mots utilisés en moyenne
pour décrire un produit est inégalement
réparti
entre les catégories, pouvant
aller pratiquement du simple au double.

6.2 Traitement du texte

Cette étape est très importante pour l'optimisation
de notre moteur de classification.

Nous allons nettoyer et normaliser nos descriptions
en effectuant un ensemble d'opérations détaillées ci-dessous.

Pour cette étape, j'utilise la bilibliothèque texthero.

6.2.1 Nettoyage et Normalisation du texte

Utilisation de text hero:

La méthode clean effectue le traitement suivant :

  1. texthero.preprocessing.fillna()
  2. texthero.preprocessing.lowercase()
     - Passe la chaîne de caractère en minuscule
  3. texthero.preprocessing.remove_digits()
     - Remplace tous les digits par un seul espace
  4. texthero.preprocessing.remove_punctuation()
     - Remplace tous les signes de
      ponctuation par un seul espace
  5. texthero.preprocessing.remove_diacritics()
     - Supprime tous les diacritiques et les accents
  6. texthero.preprocessing.remove_stopwords()
     - Supprime les stopwords issues
      d'une liste de 179 stopwords de
      la bibliothèque NLTK.
  7. texthero.preprocessing.remove_whitespace()
     - Supprime les espaces inutiles en début et
      en fin de chaîne, les sauts de ligne,
      les tabulations et toute forme d'espace

J'affiche un exemple de description,
**avant** et **après** traitement
:

**Avant** Normalisation :

**Après** Normalisation :

6.2.2 Lemmatisation du texte et
Filtrage des Noms + Verbes

Le processus de « lemmatisation » consiste
à représenter les mots (ou « lemmes »)
sous leur forme canonique.
Par exemple pour un verbe, ce sera son infinitif.
Pour un nom, son masculin singulier.
L'idée étant encore une fois de ne conserver
que le sens des mots
utilisés dans le corpus.

De plus, dans notre objectif de ne conserver que
des features permettant de décrire un objet
,
nous allons filtrer les résultats pour ne conserver
que les Noms et Verbes des descriptions.

**Avant** lemmatisation :

**Après** lemmatisation :

6.2.3 Graphique Nombre de Mots par Catégorie par Traitement

En moyenne, les étapes de cleaning et
de lematisation suppriment 49.61%
de mots inutiles à la description de nos produits.

6.2.4 Création du dictionnaire dictTxt

A partir de maintenant nous allons
manipuler différents objets.

Pour plus de simplicité,
j'utiliserai un dictionnaire
chaque clé fera référence
à l'objet utilisé
.

J'utiliserai également un ensemble
de fonctions que j'ai écrit et dont
vous trouverez les déclarations en
première partie de ce document.

Le plus souvent, ces fonctions prennent
en argument un dictionnaire
et nous
retourne un dictionnaire enrichi
d'une nouvelle clé contenant l'objet
désiré (matrice tf-idf, t-sne, etc.).

J'ai essayé de choisir des noms
de fonction explicites, n'hésitez pas
à lire leur docstring si besoin.

J'ajoute au dictionnaire la key "category"
contenant la feature "category" du DataFrame df.

6.2.5 Création des vecteurs pondérés avec TF-IDF

Nous pouvons maintenant créer notre bag of words.
Il s'agit du sac de mots, sans ordre, contenant
l'ensemble du vocabulaire conservé et
qui décrit au mieux nos produits.

Chaque produit de notre jeu de données est
caractérisé par son vocabulaire et par le
nombre d'occurrences de chacun de ses mots
de vocabulaire.

Nous pourrions donc créer un vecteur,
où chaque élément de ce vecteur correspondrait
à un mot du bac of words, et où chaque valeur
de chaque élément du vecteur correspondrait
au nombre d'occurrences du mot dans
la description du produit.

Cette approche est intéressante, on émet l'hypothèse
que des catégories de produits rassemblent certains mots
de vocabulaire spécifiques plutôt que d'autres.

Cependant, certains mots peuvent être fréquents
et commun à plusieurs ou même à toutes les catégories.
Nous allons donc relativiser l'occurrence d'un mot
en fonction de sa présence dans l'ensemble
des descriptions des produits.

Pour réaliser cela je vais utiliser tf-idf avec sklearn.

Qu'est-ce que **TF-IDF** :
Term Frequency – Inverse Document Frequency
est une mesure qui permet, à partir d’un
ensemble de textes, de connaître l’importance
relative de chaque mot.

Idéalement, un terme apparaît très fréquemment
dans quelques textes seulement.
Les mots qui apparaissent dans presque tous les
documents ou très rarement n’ont que peu d’importance.

TF-IDF va nous permettre de créer une matrice de vecteurs,
où chaque élement du vecteur représente un mot
du bag of word et la valeur de chaque élément
du vecteur représente l'importance d'un mot
relativisé à l'ensemble des documents (ici,
à l'ensemble des descriptions des produits
du jeu de données.)

Création de la matrice tf-idf :

6.2.6 Réduction de dimension PCA / T-SNE

Afin nous permettre de visualiser graphiquement
les regroupements de nos produits en fonction
de leur description mais également d'améliorer
les performances
de notre moteur de classification,
nous allons appliquer une réduction de dimension
à notre matrice tf-idf.

L'objectif ici est de ramener nos vecteurs en 2 dimensions.

Nous allons utiliser pour cela l'algorithme T-SNE.

Cependant le charge peut-être très
lourde en termps de calcul.
Pour éviter cette problématique,
nous allons appliquer une première
réduction de dimension
en appliquant
une Analyse en Composante Principale.
Nous ferons le choix de conserver 99%
de la variance
afin de ne pas sacrifier
la qualité de nos données tout en
réduisant drastiquement le temps necessaire
à l'application de T-SNE pour la réduction
en 2 dimensions de nos vecteurs TF-IDF.

Nous pouvons afficher notre matrice TF-IDF
maintenant réduite en 2 dimensions où
chaque point représente un produit
:

On peut d'ores et déjà remarquer
des regroupements parmi les produits.

6.2.7 Affichage de la classification des descriptions selon leurs catégories

Ajoutons maintenant un peu de couleur.
Chaque produit est maintenant représenté
par une couleur représentant sa catégorie
parmi les 7 existantes.

Certaines catégories semblent très bien regroupées
comme "Watches" ou "Beauty and Personal Care".
D'autres sont plus diffuses comme "Home Furnising".

On peut émettre l'hypothèse que les groupes
correctement taggés ont un vocubulaire très
spécifique
alors que les autres ont un vocubulaire
plus général
susceptible d'être présent dans
plusieurs catégories.

6.2.8 K-Means sur matrice T-SNE

L'idée à présent et de faire comme si
nous ne connaissions pas la réelle
catégorie des produits.

A partir de la matrice T-SNE, nous allons regrouper,
via l'algorithme K-Means les points selon 7 clusters.
Chaque cluster représente l'une des 7 catégories.

6.2.9 Affichage de la classification des descriptions selon leurs clusters

Affichons maintenant les produits selon leurs clusters K-Means :

Ici les clusters sont beaucoup plus
nets et bien délimités que précédement.

On constate que certains clusters
représentent assez fidèlement certaines
vraies catégories, encore une fois
comme "Watches" ou "Beauty and Personal Care".

Cependant les catégories les plus diffuses
ont bien entendu des produits mal
classés par K-Means.

6.2.10 Matrice de Confusion

Utilisons la matrice de confusion
pour visualiser les erreurs de classement.

Les catégories ont la majorité de leurs produits
qui sont correctements classés.
Les clusters peuvent être attribués à leur catégorie
respective en identifiant, pour chaque catégorie,
le cluster qui la représente le plus.
La catégorie "Computers" est la catégorie
la plus difficile à classer. Presque la moitié des produits
est attribuée à tort à la catégorie "Beauty and Personal Care."

6.2.11 Calcul du Score ARI

Pour mesurer l'erreur de notre moteur
de classification, nous allons utiliser
la métrique ARI via la fonction
adjusted_rand_score de sklearn.

L'adjusted_rand_score calcule une mesure
de similarité entre deux groupements
en considérant toutes les paires d'échantillons
et en comptant les paires qui sont assignées
dans le même groupement ou dans des groupements
différents dans les groupements prédits et réels.

Le score ARI va de 0 pour un étiquetage aléatoire
à 1 pour un étiquetage parfait
.

Selon les essais nous obtenons
un score variant de 0.44 à 0.56.
C'est un score très encourageant.

7. Classification des produits grâce à leurs images

Nous allons maintenant tenter de classer nos produits selon l'image associée à leur description.

Ici l'idée est similaire à l'analyse de texte :

  1. Obtenir des features des images,
    à partir de leurs descripteurs
  2. Créer un Bag of Virtual Words
    à partir de l'ensemble des features existantes
  3. Créer des vecteurs de caractéristiques
    à partir du Bag of Virtual Words
  4. Réaliser une réduction de dimension sur nos vecteurs
  5. Clusteriser notre matrice de vecteurs
  6. Evaluer le résultat de la clusterisation
    de notre moteur de classification avec
    la catégorie réelle associée à chaque image

Je détaille ci-dessous deux approches :

7.1 Méthode SIFT

La scale-invariant feature transform (SIFT),
que l'on peut traduire par « transformation
de caractéristiques visuelles invariante à l'échelle »,
est un algorithme utilisé pour détecter et identifier
les éléments similaires entre différentes images
numériques
(éléments de paysages, objets, personnes, etc.).
Il a été développé en 1999.

L'étape fondamentale de la méthode consiste
à calculer ce que l'on appelle les « descripteurs
SIFT
» des images à étudier.
Il s'agit d'informations numériques dérivées
de l'analyse locale d'une image et qui caractérisent
le contenu visuel de cette image de la façon
la plus indépendante possible de l'échelle (« zoom »
et résolution du capteur), du cadrage, de l'angle
d'observation et de l'exposition
(luminosité).

Ainsi, deux photographies d'un même objet auront
toutes les chances d'avoir des descripteurs SIFT
similaires
, et ceci d'autant plus si les instants
de prise de vue et les angles de vue sont proches.

Voici le protocole que l'on va mettre en place,
pour créer notre moteur de classification des
produits à partir des images avec **SIFT**
:

  1. Pour chaque image du jeu de données
    • Lire l'image
    • Réaliser le pre-processing de l'image
      pour augmenter la capacité de SIFT à
      détecter correctement les descripteurs
    • Passer l'image en niveau de gris (par
      souci de simplicité, les couleurs ne
      changent pas fondamentalement le score final)
    • Application d'un flou gaussien
    • Egalisation de l'histogramme
    • Extraction des descripteurs
  2. Création d'une matrice contenant
    l'ensemble des descripteurs
  3. Clustérisation pour création
    des Bag of Virtual Words
  4. Création des Histogrammes
  5. Réduction de dimension PCA + T-SNE
  6. Calcul du score ARI

7.1.1 Création du dictionnaire dictImages

De la même manière que la partie texte,
j'utilise un dictionnaire pour stocker
et manipuler nos données.

7.1.2 Ajout du path des images...

J'importe le chemin complet (dossier + nom de fichier)
de chaque image sous forme de Series Pandas pour
qu'elles puissent êtres accessibles facilement.

7.1.3 ...et de leurs catégories respectives

J'importe également sous forme de Series Pandas
les catégories associées à chaque image.
Comme les index sont les mêmes, l'ordre
image/categorie est respecté.

7.1.4 Calcul et regroupement de l'ensemble des descripteurs

On parcourt chacune des images referencées
dans notre dictionnaire dictImages (chaque
élement de la key "path")

Puis pour chaque image :

  1. On charge l'image pour pouvoir travailler avec
  2. On applique les pre-processing suivants :
    1. Passage en niveau de gris
    2. Flou Gaussien
    3. Egalisation de l'Histogramme
  3. On applique SIFT à l'image pré-processée
    pour extraire les descripteurs de l'image
  4. On ajoute les descripteurs à une matrice
    destinée à contenir tous les descripteurs
    de toutes les images
  5. On ajoute la matrice des descripteurs
    à la key "totalDes" de notre dictionnaire.

On obtient une matrice de 4 185 939 descripteurs.
Chaque descripteur est un vecteur de dimension (1,128).

7.1.5 A propos du pre-processing des images

J'affiche ci-dessous 1 image du jeu de données
et son histogramme associé
, en appliquant
successivement les opérations de pré-processing suivant:

  1. Aucun pré-processing
  2. Passage en niveau de gris
  3. Passage en niveau de gris + Flou Gaussien
    • Le Flou Gaussien nous sert à nettoyer l'image de son bruit.
      Il évite à SIFT de détecter de mauvais descripteurs.
  4. Passage en niveau de gris + Flou Gaussien + Egalisation de l'histogramme
    • L'égalisation de l'histogramme accentue
      le contraste de l'image et améliore les performances
      de SIFT dans la détection des descripteurs.

Attention, dans cette partie j'évoque le terme
***histogramme*** dans deux contextes différents
:

7.1.6 Création du Bag of Virtual Words

Nous cherchons à trouver l'équivalent des mots,
en tant que features, que nous avions pour
l'analyse du texte.
Pour retrouver l'équivalent des mots,
nous allons créer des mots virtuels.

Grâce à l'algorithme MiniBatchKMeans
(une variante de l'algorithme KMeans
optimisé pour réduire le temps de calcul),
nous allons clusteriser notre matrice
de descripteurs calculée précedement.

Les descripteurs dont les caractéristiques
seront proches seront naturellement regroupés
dans des clusters identiques.

Chaque centroïde sera alors considéré
comme un mot virtuel
.

La fonction **createKmeansOfBagOfVirtualWords**
définie les **deux hyperparamètres** de
**MiniBatchKMeans** de la manière suivante
:

On obtient un MiniBatchKMeans entrainé avec 2046 clusters.
Chaque centroïde de ces clusters représente les mots
de notre Bag of Virtual Words

7.1.7 Création des histogrammes

Nous allons maintenant créer les histogrammes
de nos images.
Un histogramme est un vecteur de caractéristiques.

Nous allons réaliser pour nos images le même genre
d'opération qu'avec TF-IDF pour le texte de la
partie précedente.

Un histogramme est un vecteur où chaque élement
du vecteur correspond à un mot virtuel.
La dimension de notre matrice d'histogrammes est
donc égale à (Nombre d'images, Nombre de Clusters)
soit ici (1050,2046).

Pour renseigner chaque élement du vecteur d'une image
nous réalisons les opérations suivantes
:

Une fois l'opération réalisée pour
tous les descripteurs d'une image,
l'histogramme est finalisé.

Nous réalisons cette opération
pour toutes les images.

Nous obtenons une matrice de
dimension (Nombre d'images, Nombre de mots virtuels
(c'est à dire de centroïdes dans le MiniBatchKMeans
entrainé) ce qui correspond dans notre cas à (1050,2046)

7.1.8 Réduction de dimension PCA / T-SNE

Afin nous permettre de visualiser graphiquement
les regroupements de nos produits en fonction
de leur description mais également d'améliorer
les performances
de notre moteur de classification,
nous allons appliquer une réduction de dimension
à notre matrice de vecteurs.

L'objectif ici est de ramener nos vecteurs en 2 dimensions.

Nous allons utiliser pour cela l'algorithme T-SNE.

Cependant la charge peut-être très
lourde en temps de calcul.
Pour éviter cette problématique,
nous allons appliquer une première
réduction de dimension
en appliquant
une Analyse en Composante Principale.
Nous ferons le choix de conserver 99%
de la variance
afin de ne pas sacrifier
la qualité de nos données tout en
réduisant drastiquement le temps nécessaire
à l'application de T-SNE pour la réduction
en 2 dimensions de nos histogrammes.

Nous pouvons afficher notre matrice d'histogrammes
maintenant réduite en 2 dimensions où
chaque point représente un produit
:

A ce stade, aucun regroupement de points ne semble se démarquer.

7.1.9 Affichage de la classification des images selon leurs catégories

Ajoutons maintenant un peu de couleur.
Chaque produit est maintenant représenté
par une couleur représentant sa catégorie
parmi les 7 existantes.

Il est très difficile de distinguer
des regroupements selon les catégories.

7.1.10 K-Means sur matrice T-SNE

L'idée à présent et de faire comme si
nous ne connaissions pas la réelle
catégorie des produits.

A partir de la matrice T-SNE, nous allons regrouper,
via l'algorithme K-Means les points selon 7 clusters.
Chaque cluster représente l'une des 7 catégories.

7.1.11 Affichage de la classification des images selon leurs clusters

Affichons maintenant les produits selon leurs clusters K-Means :

Les points sont ici regroupées d'une manière beaucoup plus homogène.

7.1.13 Matrice de Confusion

Utilisons la matrice de confusion
pour visualiser les erreurs de classement.

Les catégories sont mal classées et il est impossible
d'associer avec certitude une catégorie à un numéro de cluster.

7.1.12 Calcul du Score ARI

Pour mesurer l'erreur de notre moteur
de classification, nous allons utiliser
la métrique ARI via la fonction
adjusted_rand_score de sklearn.

L'adjusted_rand_score calcule une mesure
de similarité entre deux groupements
en considérant toutes les paires d'échantillons
et en comptant les paires qui sont assignées
dans le même groupement ou dans des groupements
différents dans les groupements prédits et réels.

Le score ARI va de 0 pour un etiquetage aléatoire
à 1 pour un étiquetage parfait
.

Nous obtenons un score d'environ 7.5%
Celà peut parraitre peu mais les images
n'étaient vraiment pas optimisées ni en nombre suffisant.
Ce score peut-être amélioré.

7.2 Méthode Transfert Learning avec VGG16

Nous allons dans cette partie utiliser Keras,
une bibliothèque de Deep Learning.

Nous utiliserons une version du réseau de neurones
convolutif VGG-Net nommé **VGG16**
.

Le modèle VGG16 atteint une précision de 92,7%
dans le top 5 des tests d'ImageNet.
ImageNet est un ensemble de données de plus
de 15 millions d'images haute résolution
étiquetées
appartenant à environ 22 000 catégories.

Keras nous fourni une version pré-entraînée de VGG16.

Pour mettre en place notre moteur de classification
d'images, nous appliquerons une technique
nommée Transfert Learning.

Simplement, le Transfert Learning consiste
à utiliser la connaissance déjà acquise
par un modèle entraîné (ici VGG16) pour l'adapter
à notre problématique.

Actuellement VGG16 permet de classer une image
parmi 1000 catégories différentes.

Nous souhaitons donc pouvoir utiliser
la puissance de **VGG16**
mais adaptée à
notre problématique
. C'est à dire pouvoir
classer une image non pas parmi 1000 catégories
mais parmi nos 7 catégories.

7.2.1 Installer Keras

Avant d'aller plus loin,
vous devrez installer Keras.

Pour installer Keras :

7.2.2 Explication rapide de VGG16

Voici une vue des différentes couches de VGG16 :

Représentation VGG16

VGG-16 est constitué de plusieurs couches,
dont 13 couches de convolution et 3 fully-connected.

Il prend en entrée une image en couleurs de taille 224 × 224 px
et la classifie dans une des 1000 classes.
Il renvoie donc un vecteur de taille 1000,
qui contient les probabilités d'appartenance
à chacune des classes.

Dans notre approche Transfert Learning, nous n'allons
pas utiliser la dernière couche softmax chargée de
classer l'image parmi l'une des 1000 catégories.

Nous récupérerons, pour chaque image, le vecteur
de dimension (1,1,4096), puis, comme pour la méthode SIFT,
ou pour le traitement du texte que nous avons
réalisé précedement dans ce projet, nous répéterons
les étapes de :

7.2.3 Création du modèle pré-entrainé par Keras

Nous allons dans un premier temps importer le modèle VGG16.
Puis nous créerons ensuite notre propre modèle,
qui sera une copie de VGG16 à l'exception de
la dernière couche **softmax**
.

Création du modèle VGG-16 implémenté par Keras :

On indique qu'on ne souhaite ré-entrainer
aucune des couches du modèle
:

On définit le nouveau modèle en
définissant son entrée et sa sortie
:

En entrée, nous voulons utiliser l'entrée du modèle VGG16
En sortie, nous souhaitons obtenir le vecteur généré
par VGG16 juste avant la dernière couche softmax,
soit son avant-dernière couche.

Pour s'assurer que le nouveau modèle est
bien configuré, j'affiche son résumé que
je compare avec le modèle VGG16 initial
:

Résumé du modèle VGG16 :

Résumé de notre nouveau modèle :
On remarque que la dernière couche
n'a pas été importée et que le modèle
ne va pas être ré-entrainé, même partiellement.

7.2.4 Création du dictionnaire dictModel

Comme précedement, j'utilise un dictionnaire
pour stocker et manipuler nos données.

7.2.5 Ajout du path des images...

J'importe le chemin complet (dossier + nom de fichier)
de chaque image sous forme de Series Pandas pour
qu'elles puissent être accessibles facilement.

7.2.6 ...et de leurs catégories respectives

J'importe également sous forme de Series Pandas
les catégories associées à chaque image.
Comme les index sont les mêmes, l'ordre
image/catégorie est respecté.

7.2.7 Préparation des images

VGG16 attend en entrée une matrice d'images
en 4 dimensions composée de la façon suivante
:

Préparons les images au bon format
pour notre Model basé sur VGG16
:

  1. Je crée un matrice d'images en 4 dimensions
  2. Chaque image est préalablement redimensionnée
    avec les dimensions 224 x 224 px.
  3. La matrice est stockée à l'intérieur du
    dictionnaire sous la clé "arrayImg".

7.2.8 Extraction des histogrammes

Pour obtenir nos histogrammes avec notre
nouveau modèle, il suffit d'utiliser la méthode
predict en passant en argument la matrice
d'images en 4 dimensions.

Le modèle nous retourne une matrice
de (ici 1050) vecteurs, où chaque vecteur
est de dimension (1, 4096).

7.2.9 Clustering PCA / T-SNE

Afin nous permettre de visualiser graphiquement
les regroupements de nos produits en fonction
de leur description mais également d'améliorer
les performances
de notre moteur de classification,
nous allons appliquer une réduction de dimension
à notre matrice de vecteurs.

L'objectif ici est de ramener nos vecteurs en 2 dimensions.

Nous allons utiliser pour cela l'algorithme T-SNE.

Cependant la charge peut-être très
lourde en temps de calcul.
Pour éviter cette problématique,
nous allons appliquer une première
réduction de dimension
en appliquant
une Analyse en Composante Principale.
Nous ferons le choix de conserver 99%
de la variance
afin de ne pas sacrifier
la qualité de nos données tout en
réduisant drastiquement le temps nécessaire
à l'application de T-SNE pour la réduction
en 2 dimensions de nos histogrammes.

Nous pouvons afficher notre matrice d'histogrammes
maintenant réduite en 2 dimensions où
chaque point représente un produit
:

Les produits semblent nettement plus répartis
par groupe que lors de l'utilisation de SIFT.
Même si à ce stade il n'est pas possible de
savoir à quel point le moteur de classification
sera efficace, cette première représentation
avec notre model basé sur VGG16 semble plus
efficace que la méthode SIFT.

7.2.10 Affichage de la classification des images selon leurs catégories

Ajoutons maintenant un peu de couleur.
Chaque produit est maintenant représenté
par une couleur représentant sa catégorie
parmi les 7 existantes.

Comme pour le classement à partir de la description
texte des images, certaines catégories semblent
très bien regroupées comme "Watches" ou "Beauty and Personal Care".
D'autres sont plus diffuses comme "Home Furnising".

On peut émettre l'hypothèse que les groupes
correctement taggués ont des caractéristiques visuelles très
spécifiques alors que les autres ont des caractéristiques
plus générales et susceptibles d'être présentes dans
plusieurs catégories.

7.2.11 K-Means sur matrice T-SNE

L'idée à présent et de faire comme si
nous ne connaissions pas la réelle
catégorie des produits.

A partir de la matrice T-SNE, nous allons regrouper,
via l'algorithme K-Means les points selon 7 clusters.
Chaque cluster représente l'une des 7 catégories.

7.2.12 Affichage de la classification des images selon leurs clusters

Affichons maintenant les produits selon leurs clusters K-Means :

Ici les clusters sont beaucoup plus
nets et bien délimités que précedement.

On constate que certains clusters
représentent assez fidèlement certaines
vraies catégories, encore une fois
comme "Watches" ou "Beauty and Personal Care".

Cependant les catégories les plus diffuses
ont bien entendu des produits mal
classés par K-Means.

7.2.13 Matrice de Confusion

Utilisons la matrice de confusion
pour visualiser les erreurs de classement.

Certaines catégories ont leurs produits
qui sont correctements classés.
D'autres catégories n'ont pas pu être associées
clairement à un cluster comme la catégorie "Baby Care".

Il est impossible d'associer avec certitude
une catégorie à un numéro de cluster.

7.2.14 Calcul du Score ARI

Pour mesurer l'erreur de notre moteur
de classification, nous allons utiliser
la métrique ARI via la fonction
adjusted_rand_score de sklearn.

L'adjusted_rand_score calcule une mesure
de similarité entre deux groupements
en considérant toutes les paires d'échantillons
et en comptant les paires qui sont assignées
dans le même groupement ou dans des groupements
différents dans les groupements prédits et réels.

Le score ARI va de 0 pour un étiquetage aléatoire
à 1 pour un étiquetage parfait
.

Selon les essais nous obtenons
un score variant de 0.45 à 0.50.
C'est un score très encourageant.

8. Fusion des features Textes et Images

Nous avons testé notre moteur de classification à partir
des textes de description des produits puis de leurs images,
nous allons tenter d'améliorer l'efficacité de notre
moteur de classification
en fusionnant les vecteurs
de caractéristiques
obtenus avec TF-IDF pour l'analyse textuelle,
puis les vecteurs issus de notre modèle basé sur **VGG16**
pour l'analyse des images.

Nous obtiendrons ainsi, pour chaque produit, un unique vecteur
de caractéristiques
provenant à la fois des features
textes et images
.

Les étapes de réalisation seront exactement
les mêmes que vu précedement.
Je ne rentrerai donc pas dans les détails dans cette partie.

8.1 Création et initialisation du dictionnaire dictTxt

Je crée un nouveau dictionnaire dans lequel j'importe :

8.2 Fusion des vecteurs de caractéristiques de textes et d'images

Je combine les deux matrices de vecteurs en une seule
et je stocke cette nouvelle matrice dans
la clé "vectors" du dictionnaire dictTxtImages.

8.3 Clustering PCA / T-SNE

On effectue la réduction des vecteurs en 2 dimensions :

Nous pouvons afficher notre matrice d'histogrammes
maintenant réduite en 2 dimensions où
chaque point représente un produit
:

8.4 Affichage de la classification des produits selon leurs catégories

Ajoutons maintenant un peu de couleur.
Chaque produit est maintenant représenté
par une couleur représentant sa catégorie
parmi les 7 existantes.

Comme pour le classement à partir de la description
texte des images, certaines catégories semblent
très bien regroupées comme "Watches" ou "Beauty and Personal Care".
D'autres sont plus diffuses comme "Home Furnising".

8.5 K-Means sur matrice T-SNE

L'idée est toujours de faire comme si
nous ne connaissions pas la réelle
catégorie des produits.

A partir de la matrice T-SNE, nous allons regrouper,
via l'algorithme K-Means les points selon 7 clusters.
Chaque cluster représente l'une des 7 catégories.

8.6 Graphique Description/Cluster

Affichons maintenant les produits selon leurs clusters K-Means :

8.7 Matrice de Confusion

Utilisons la matrice de confusion
pour visualiser les erreurs de classement.

Certaines catégories ont leurs produits
qui sont correctements classés.
D'autres catégories n'ont pas pu être associées
clairement à un cluster comme la catégorie "Baby Care
ou la catégorie "Kitchen & Dining".

Il est impossible d'associer avec certitude
une catégorie à un numéro de cluster.

8.8 Calcul du Score ARI

Pour mesurer l'erreur de notre moteur
de classification, nous allons utiliser
la métrique ARI via la fonction
adjusted_rand_score de sklearn.

L'adjusted_rand_score calcule une mesure
de similarité entre deux groupements
en considérant toutes les paires d'échantillons
et en comptant les paires qui sont assignées
dans le même groupement ou dans des groupements
différents dans les groupements prédits et réels.

Le score ARI va de 0 pour un étiquetage aléatoire
à 1 pour un étiquetage parfait
.

Nous obtenons un score de même ordre de grandeur
qu'avec utilisation seul du moteur de classification
textuel ou par image avec le model basé sur VGG16.

9 Conclusion

Nous avons successivement tenté de classer
nos produits à partir de leurs données
descriptives textuelles ainsi qu'à partir
de leurs images.
Nous avons ensuite tenté de classer les
produits en **fusionnant** les données textes
et images
.

Les tests ont été réalisé à parti d'un
petit échantillon de 1050 produits.

A ce stade la classification à partir
des données textes (titre + description)
donne les résultats les plus satisfaisant.
L'analyse d'image n'apporte pas de précision
supplémentaire.

Cependant, la précision du moteur de classification
basé sur l'analyse des images peut être grandement
améliorés
si nous décidons, par exemple, de ré-entrainer
un modèle basé sur VGG16 à partir d'une base
d'images correspondant à nos catégories de produits.

Globalement les résultats sont très encourageants
et nous permettent de donner un avis **positif**
sur la faisabilité du moteur de classification
.